home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Bbox.c - computes bounding boxes for objects. *
- *******************************************************************************
- * Written by Gershon Elber, June 1993. *
- ******************************************************************************/
-
- #include "irit_sm.h"
- #include "allocate.h"
- #include "cagd_lib.h"
- #include "bbox.h"
-
- #define RESET_BBOX(Bbox) { Bbox.Min[0] = Bbox.Min[1] = Bbox.Min[2] = INFINITY;\
- Bbox.Max[0] = Bbox.Max[1] = Bbox.Max[2] = -INFINITY; }
-
- #define SET_IF_LESS_THAN(Val, NewVal) { if (NewVal < Val) Val = NewVal; }
- #define SET_IF_GREATER_THAN(Val, NewVal) { if (NewVal > Val) Val = NewVal; }
- #define SET_PT_IF_LESS_THAN(Pt, NewPt) { SET_IF_LESS_THAN(Pt[0], NewPt[0]) \
- SET_IF_LESS_THAN(Pt[1], NewPt[1]) \
- SET_IF_LESS_THAN(Pt[2], NewPt[2]) }
- #define SET_PT_IF_GREATER_THAN(Pt, NewPt) \
- { SET_IF_GREATER_THAN(Pt[0], NewPt[0]) \
- SET_IF_GREATER_THAN(Pt[1], NewPt[1]) \
- SET_IF_GREATER_THAN(Pt[2], NewPt[2]) }
-
- /*****************************************************************************
- * Computes a bounding box of a given object of any type. *
- *****************************************************************************/
- BBBboxStruct *BBComputeBboxObject(IPObjectStruct *PObj)
- {
- static BBBboxStruct Bbox;
- int i;
- IPObjectStruct *PObjTmp;
- BBBboxStruct *PBbox;
- CagdBBoxStruct CagdBbox;
-
- switch (PObj -> ObjType) {
- case IP_OBJ_POLY:
- return BBComputePolyListBbox(PObj -> U.Pl);
- case IP_OBJ_POINT:
- return BBComputePointBbox(PObj -> U.Pt);
- case IP_OBJ_VECTOR:
- return BBComputePointBbox(PObj -> U.Vec);
- case IP_OBJ_LIST_OBJ:
- RESET_BBOX(Bbox);
- PBbox = &Bbox;
- for (i = 0; (PObjTmp = ListObjectGet(PObj, i++)) != NULL; )
- PBbox = BBMergeBbox(PBbox, BBComputeBboxObject(PObjTmp));
- return PBbox;
- case IP_OBJ_CURVE:
- CagdCrvListBBox(PObj -> U.Crvs, &CagdBbox);
- GEN_COPY(Bbox.Min, CagdBbox.Min, 3 * sizeof(RealType));
- GEN_COPY(Bbox.Max, CagdBbox.Max, 3 * sizeof(RealType));
- return &Bbox;
- case IP_OBJ_SURFACE:
- CagdSrfListBBox(PObj -> U.Srfs, &CagdBbox);
- GEN_COPY(Bbox.Min, CagdBbox.Min, 3 * sizeof(RealType));
- GEN_COPY(Bbox.Max, CagdBbox.Max, 3 * sizeof(RealType));
- return &Bbox;
- default:
- RESET_BBOX(Bbox);
- return &Bbox;
- }
- }
-
- /*****************************************************************************
- * Computes a bounding box of a given object list of any type. *
- *****************************************************************************/
- BBBboxStruct *BBComputeBboxObjectList(IPObjectStruct *PObj)
- {
- BBBboxStruct Bbox, *PBbox;
-
- RESET_BBOX(Bbox);
- PBbox = &Bbox;
-
- for ( ; PObj != NULL; PObj = PObj -> Pnext) {
- PBbox = BBMergeBbox(PBbox, BBComputeBboxObject(PObj));
- }
-
- return PBbox;
- }
-
- /******************************************************************************
- * Computes a bounding box around a single polygon. *
- ******************************************************************************/
- BBBboxStruct *BBComputeOnePolyBbox(IPPolygonStruct *PPoly)
- {
- static BBBboxStruct Bbox;
- IPVertexStruct
- *V = PPoly -> PVertex;
-
- RESET_BBOX(Bbox);
-
- do {
- SET_PT_IF_LESS_THAN(Bbox.Min, V -> Coord);
- SET_PT_IF_GREATER_THAN(Bbox.Max, V -> Coord);
- V = V -> Pnext;
- }
- while (V != NULL && V != PPoly -> PVertex);
-
- return &Bbox;
- }
-
- /******************************************************************************
- * Computes a bounding box around a list of polygons. *
- ******************************************************************************/
- BBBboxStruct *BBComputePolyListBbox(IPPolygonStruct *PPoly)
- {
- static BBBboxStruct Bbox;
-
- RESET_BBOX(Bbox);
-
- for ( ; PPoly != NULL; PPoly = PPoly -> Pnext) {
- IPVertexStruct
- *V = PPoly -> PVertex;
-
- do {
- SET_PT_IF_LESS_THAN(Bbox.Min, V -> Coord);
- SET_PT_IF_GREATER_THAN(Bbox.Max, V -> Coord);
- V = V -> Pnext;
- }
- while (V != NULL && V != PPoly -> PVertex);
- }
-
- return &Bbox;
- }
-
- /******************************************************************************
- * Computes a bounding box around a point. *
- ******************************************************************************/
- BBBboxStruct *BBComputePointBbox(RealType *Pt)
- {
- static BBBboxStruct Bbox;
-
- PT_COPY(Bbox.Min, Pt);
- PT_COPY(Bbox.Max, Pt);
-
- return &Bbox;
- }
-
- /******************************************************************************
- * Merge (union) two bounding boxes into one. *
- * Either Bbox1 or Bbox2 can be pointing to the static area Bbox. *
- ******************************************************************************/
- BBBboxStruct *BBMergeBbox(BBBboxStruct *Bbox1, BBBboxStruct *Bbox2)
- {
- static BBBboxStruct Bbox;
- int i;
-
- /* Make sure first Bbox is in Bbox and Bbox2 holds the other one. */
- if (Bbox1 == &Bbox) {
- }
- if (Bbox2 == &Bbox) {
- Bbox2 = Bbox1;
- }
- else {
- GEN_COPY(&Bbox, Bbox1, sizeof(BBBboxStruct));
- }
-
- /* Compare the two Bbox's and update. */
- for (i = 0; i < 3; i++) {
- if (Bbox.Min[i] > Bbox2 -> Min[i])
- Bbox.Min[i] = Bbox2 -> Min[i];
- if (Bbox.Max[i] < Bbox2 -> Max[i])
- Bbox.Max[i] = Bbox2 -> Max[i];
- }
-
- return &Bbox;
- }
-